import { strTrim } from './utils.js'
// reflect mysql type to js type
export const reflectType = (field) => {
  switch (field.dataType) {
    case 'tinyint':
    case 'bigint':
    case 'smallint':
    case 'mediumint':
    case 'int':
    case 'float':
    case 'double':
    case 'decimal':
      return 'number'
    case 'char':
    case 'varchar':
      return FieldIsArray(field)
    case 'set':
      return 'Array<string>'
    case 'enum':
    case 'text':
    case 'mediumtext':
    case 'longtext':
    case 'datetime':
    case 'date':
    case 'timestamp':
      return 'string'
  }
}
// reflct comment to desc
export const reflectDesc = (field) => {
  // e1: status:1=open,2=close
  // e2: this is a comment
  if (field.columnComment) {
    return field.columnComment.split('|')[0].split(':')[0]
  } else {
    return ''
  }
}
export const reflectOptions = (field) => {
  // const comment = field.columnComment.split('|')[0].split(':')
  if (!field.columnComment) return ''
  const comment = field.columnComment.split('|')
  const empty = []
  if (comment.length >= 2) {
    const index = comment.findIndex((item, index) => item !== 'ignored' && item != 'list' && index > 0)
    if(index == -1) return
    const options = strTrim(comment[index]).split(',')
    options.forEach((option) => {
      const labelValue = option.split('=')
      const label = labelValue[1]
      const value = labelValue[0]
      empty[label] = value
    })
  }
  return empty
}

// reflect the type of field   to array or string
const FieldIsArray = (field) => {
  if (field.dataType === 'set') {
    return 'Array<string>'
  } else if ((field.reflectColumnName.split('images').slice(-1)[0] === '' && field.dataType === 'varchar')) {
    return 'Array<string>'
  } else if (field.reflectColumnName.split('files').slice(-1)[0] === '' && field.dataType === 'varchar') {
    return 'Array<string>'
  } else if (field.reflectColumnName.split('tags').slice(-1)[0] === '' && field.dataType === 'varchar') {
    return 'Array<string>'
  }
  return 'string'
}

// reflect comment and type to rule
export const reflectRule = (field) => {
  const rules = []
  const comment = field.columnComment.split('|')
  if (field.reflectColumnName.indexOf('_id') !== -1 && field.reflectColumnName.split('_id').slice(-1)[0] === '') {
    rules.push(`{ required: true, message: '${comment[0]}必需', trigger: ['blur', 'change'] }`)
    rules.push(`{
      trigger:['blur','change'],
      validator:(rule:any,value:any,callback:any)=>{
        if(!Number(value)){
          return callback(new Error('${comment[0]}必需'))
        }else{
          callback()
        }
      }
    }
    `)
  } else if (field.isNullable === 'NO') {
    rules.push(`{ required: true, message: '${comment[0]}必需', trigger: ['blur', 'change'] }`)
  }

  const pattern = /\((\S+)\)/
  let result = pattern.exec(field.columnType)
  let min = 0
  let max = 0
  switch (field.dataType) {
    case 'tinyint':
      if (field.columnType.indexOf('unsigned') > -1) {
        min = 0
        max = 256
      } else {
        min = -128
        max = 127
      }
      break
    case 'smallint':
      if (field.columnType.indexOf('unsigned') > -1) {
        min = 0
        max = 65536
      } else {
        min = -32768
        max = 32767
      }
      break
    case 'mediumint':
      if (field.columnType.indexOf('unsigned') > -1) {
        min = 0
        max = 16777216
      } else {
        min = -8388608
        max = 8388607
      }
      break
    case 'int':
      if (field.columnType.indexOf('unsigned') > -1) {
        min = 0
        max = 4294967296
      } else {
        min = -2147483648
        max = 2147483647
      }
      break
    case 'decimal':
      if (field.columnType.indexOf('unsigned') > -1) {
        min = 0
      } else {
        min = -9999999999
      }
      if (result) {
        result = result[1].split(',')
        if (result.length === 2) {
          max = Number(`${'9999999999'.substring(0, result[0] - result[1]) + '.' + '9999999'.substring(0, result[1])}`)
          if (field.columnType.indexOf('unsigned') === -1) {
            rules.min = -rules.max
          }
        }
      } else {
        max = 9999999999
      }
      break
    case 'char':
      max = Number(result[1])
      break
    case 'varchar':
      max = Number(result[1])
      break
    case 'tinytext':
      max = 255
      break
    case 'text':
      max = 65535
      break
    case 'mediumtext':
      max = 16777215
      break
    case 'longtext':
      max = 4294967295
      break
    case 'enum':
      rules.push(`{type: 'enum', enum: [${result[1]}],trigger:['blur','change'], message: "可选值为${result[1]}"}`)
      break
    case 'set':
      rules.push(`{
        trigger:['blur','change'],
        validator:(rule:any,value:any,callback:any)=>{
          const values = value.join(',')
          if("${result[1]}".indexOf(values) === -1){
            return callback(new Error(\`'可选值为"${result[1]}"'\`))
          }else{
            callback()
          }
        }
      }
      `)
      break
    default:
      break
  }
  // special field
  switch (field.reflectColumnName) {
    case 'phone':
      rules.push(`{ type: 'number', trigger: ['blur', 'change'],validator:(rule:any,value:any,callback:any)=>{
        const regx = /^[1][3-9][\\d]{9}/
        const result = regx.test(value)
        if (!result) {
          return callback(new Error('请输入正确手机号'))
        }else{
          callback()
        }
      }}`)
      break
    case 'email':
      rules.push("{ type: 'email', message: '请输入正确邮箱', trigger: ['blur', 'change'] }")
      break
  }

  // other rules
  const leng = comment.length
  // let range = ''
  for (let i = 1; i < leng; i++) {
    if (comment[i].indexOf('length') > -1) {
      // max and min
      const length = comment[i].split('length=')
      const maxMin = length[1].split(',')
      max = Number(maxMin.slice(-1)[0])
      min = Number(maxMin.slice(-2)[0] ? maxMin.slice(-2)[0] : '0')
    } else if (comment[i].indexOf('min=') > -1) {
      min = comment[i].split('min=')[1]
    } else if (comment[i].indexOf('max=') > -1) {
      const iMax = comment[i].split('max=')[1]
      if (iMax <= max && iMax>=min) {
        max = iMax  // 设置优先
      }
      // const iMax = comment[i].split('max=')[1]
      // if (iMax > min) {
      //   max = iMax
      // }
    }

    else if (comment[i].indexOf('range=') > -1) {
      range = comment[i].split('range=')[1]
    }
  }

  if ('tinyint/smallint/mediumint/int/decimal'.indexOf(field.dataType) > -1) {
    if (field.reflectColumnName.indexOf('_id') === -1 || field.reflectColumnName.split('_id').slice(-1)[0] !== '') {
      rules.push(`{ type:'number',min: ${min}, max: ${max}, message: '最小值为${min},最大值为${max}', trigger: ['blur', 'change'] }`)
    }
  }else if(field.dataType === 'varchar'){
    if (max) {
      rules.push(`{ max: ${max}, message: '最大长度为${max}', trigger: ['blur', 'change'] }`)
      }
    else if (min) {
        rules.push(`{ min: ${min}, message: '最小长度为${min}', trigger: ['blur', 'change'] }`)
      }
  }
  // else if (max) {
  //     rules.push(`{ type:'array',max: ${max}, message: '最大个数为${max}个', trigger: ['blur', 'change'] }`)
  //   }
  // else   if (min) {
  //     rules.push(`{ type:'array',min: ${min}, message: '最小个数为${min}个', trigger: ['blur', 'change'] }`)
  //   }
  // else if ((field.reflectColumnName.split('image').slice(-1)[0] === '' && field.dataType === 'varchar') || (field.reflectColumnName.split('images').slice(-1)[0] === '' && field.dataType === 'varchar') || (field.reflectColumnName.split('tag').slice(-1)[0] === '' && field.dataType === 'varchar') || (field.reflectColumnName.split('tags').slice(-1)[0] === '' && field.dataType === 'varchar')) {
  //   if (max) {
  //     rules.push(`{ type:'array',max: ${max}, message: '最大个数为${max}个', trigger: ['blur', 'change'] }`)
  //   }
  //   if (min) {
  //     rules.push(`{ type:'array',min: ${min}, message: '最小个数为${min}个', trigger: ['blur', 'change'] }`)
  //   }
  //   if (range) {
  //     rules.push(`{ type:'array',range: ${range}, message: '长度范围为${range}', trigger: ['blur', 'change'] }`)
  //   }
  // }
  return rules
}
// reflect type to component
export const reflectComponent = (field) => {
  // special type
  let component = ''
  switch (field.dataType) {
    case 'tinyint':
    case 'smallint':
    case 'mediumint':
    case 'decimal':
      component = 'inputNumber'
      break
    case 'int':
      if (field.reflectColumnName.indexOf('_id') === -1 || field.reflectColumnName.split('_id').slice(-1)[0] !== '') {
        component = 'inputNumber'
      } else {
        component = 'selectSingle'
      }
      break
    case 'enum':
      component = 'selectSingle'
      break
    case 'set':
      component = 'selectMulti'
      break
    case 'text':
      component = 'richText'
      break
    case 'timestamp':
      component = 'datePicker'
      break
    default:
      component = 'input'
      break
  }
  const fieldName = field.reflectColumnName || field.columnName

  // special characters with special ending
  if (fieldName.split('time').slice(-1)[0] === '' && (field.dataType === 'int' || field.dataType === 'timestamp')) {
    component = 'datePicker'
  } else if (fieldName.split('image').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'uploadImage'
  } else if (fieldName.split('images').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'uploadImages'
  } else if (fieldName.split('file').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'uploadFile'
  } else if (fieldName.split('files').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'uploadFile'
  } else if (fieldName.split('avatar').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'uploadAvatar'
  } else if (fieldName.split('content').slice(-1)[0] === '' && ('text/mediumtext/longtext').indexOf(field.dataType) > -1) {
    component = 'richText'
  } else if (fieldName.split('_id').slice(-1)[0] === '' && 'int/varchar'.indexOf(field.dataType) > -1) {
    component = 'selectSingle'
  } else if (fieldName.split('_ids').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'selectMulti'
  } else if (fieldName.split('list').slice(-1)[0] === '' && field.dataType === 'enum') {
    component = 'selectSingle'
  } else if (fieldName.split('list').slice(-1)[0] === '' && field.dataType === 'set') {
    component = 'selectMulti'
  } else if (fieldName.split('data').slice(-1)[0] === '' && field.dataType === 'enum') {
    component = 'radio'
  } else if (fieldName.split('data').slice(-1)[0] === '' && field.dataType === 'set') {
    component = 'checkbox'
  } else if (fieldName.split('json').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'inputJson'
  } else if (fieldName.split('switch').slice(-1)[0] === '' && field.dataType === 'tinyint') {
    component = 'formSwitch'
  } else if (fieldName.split('tag').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'tag'
  } else if (fieldName.split('tags').slice(-1)[0] === '' && field.dataType === 'varchar') {
    component = 'tags'
  }
  return component
}

export const reflectInputNumberParams = (field) => {
  const pattern = /\((\S+)\)/
  let result = pattern.exec(field.columnType)
  const params = {
    min: 0,
    max: 0,
    step: 0
  }
  switch (field.dataType) {
    case 'tinyint':
      if (field.columnType.indexOf('unsigned') > -1) {
        params.max = 256
      } else {
        params.min = -128
        params.max = 127
      }
      params.step = 1
      break
    case 'smallint':
      if (field.columnType.indexOf('unsigned') > -1) {
        params.max = 65536
      } else {
        params.min = -32768
        params.max = 32767
      }
      params.step = 1
      break
    case 'mediumint':
      if (field.columnType.indexOf('unsigned') > -1) {
        params.max = 16777216
      } else {
        params.min = -8388608
        params.max = 8388607
      }
      params.step = 1
      break
    case 'int':
      if (field.columnType.indexOf('unsigned') > -1) {
        params.max = 4294967296
      } else {
        params.min = -2147483648
        params.max = 2147483647
      }
      params.step = 1
      break
    case 'decimal':
      if (field.columnType.indexOf('unsigned') === -1) {
        params.min = -9999999999
      }
      if (result) {
        result = result[1].split(',')
        if (result.length === 2) {
          params.max = Number(`${'9999999999'.substring(0, result[0] - result[1]) + '.' + '9999999'.substring(0, result[1])}`)
          if (field.columnType.indexOf('unsigned') === -1) {
            params.min = -params.max
          }
        }
      } else {
        params.max = 9999999999
      }
      if (params.max > 1 && params.min < -1) {
        params.step = 1
      } else {
        params.step = 0.1
      }
      break
  }
  return params
}
